#include "music.h"
#include <QUuid>
#include <QMediaPlayer> //媒体播放类 需要添加multimedia音乐播放模块
#include <QDebug>
#include <QCoreApplication>
#include <QSqlQuery>
#include <QSqlError>
Music::Music()
    :isLike(false)
    ,isHistory(false)
{

}
//通过url构造一个Music对象
Music::Music(QUrl url)
    :isLike(false)
    ,isHistory(false)
    ,musicUrl(url)
{
    //读取url对应的歌曲文件的信息。解析出元数据
    //解析出 歌曲名称 歌曲作者 歌曲专辑 歌曲持续时长

    //给当前音乐对象获取一个UUID并赋值
    musicId=QUuid::createUuid().toString();
    //解析元数据-根据QUrl解析音乐的各种信息
    parseMediaMetaMusic();

}
//设置歌曲id
void Music::setMusicId(const QString &musicId)
{
    this->musicId=musicId;
}
//设置歌曲名称
void Music::setMusicName(const QString& musicName)
{
    this->musicName=musicName;
}
//设置歌曲作者
void Music::setMusicSinger(const QString& musicSinger)
{
    this->musicSinger=musicSinger;
}
//设置歌曲专辑
void Music::setMusicAlbumn(const QString& musicAlbumn)
{
    this->musicAlbumn=musicAlbumn;
}
//设置歌曲时长
void Music::setMusicDuration(qint64 duration)
{
    this->duration=duration;
}
//设置歌曲是否收藏
void Music::setIsLike(bool isLike)
{
    this->isLike=isLike;
}
//设置歌曲是否为历史播放
void Music::setIsHistory(bool isHistory)
{
    this->isHistory=isHistory;
}
//设置歌曲的URL
void Music::setMusicUrl(QUrl musicUrl)
{
    this->musicUrl=musicUrl;
}

//获取歌曲名称
QString Music::getMusicName()const
{
    return this->musicName;
}
//获取歌曲作者
QString Music::getMusicSinger()const
{
    return this->musicSinger;
}
//获取歌曲专辑
QString Music::getMusicAlbumn()const
{
    return this->musicAlbumn;
}
//获取歌曲时长
qint64 Music::getMusicDuration()const
{
    return this->duration;
}
//获取歌曲是否收藏
bool Music::getIsLike()const
{
    return this->isLike;
}
//获取歌曲是否为历史播放
bool Music::getIsHistory()const
{
    return this->isHistory;
}
//获取歌曲的URL
QUrl Music::getMusicUrl()const
{
    return this->musicUrl;
}
//获取UUID
QString Music::getMusicId() const
{
    return this->musicId;
}
//获取此Music的Lrc歌词文件路径
QString Music::getLrcFilePath() const
{
    //D:/music/2002年的第一场雪.mp3  歌曲文件路径
    //D:/music/2002年的第一场雪.lrc  歌词文件路径
    //利用歌曲文件路径来获取歌词文件路径
    //获取歌曲文件路径-转化为本地文件路径
    QString lrcPath=musicUrl.toLocalFile();
    //后缀替换 用.lrc替换.mp3等音乐歌曲文件路径
    lrcPath.replace(".mp3",".lrc");
    lrcPath.replace(".flac",".lrc");
    lrcPath.replace(".mpga",".lrc");
    //返回歌词文件路径
    return lrcPath;
}
//将Music歌曲属性写入到数据库中
void Music::InsertMusicToDB()
{
    //1、检测music是否在数据库中存在
    QSqlQuery query;
    //query.prepare("select * from MusicInfo where musicId=?");
    //效率低下，因为要返回符合条件记录的所有列
    //现在只需要检测musicId的歌曲是否存在
    //query.prepare("select id from MusicInfo where musicId=?");
    //原表中9列，现在只需要返回1列即可
    //在MusicInfo表中查询MusicId等于指定值的歌曲，如果歌曲存在，返回记录中只包含一个1
    //假设musicId的歌曲在MusicInfo中存在3个
    //select 1 from MusicInfo where musicId=? 返回结果为：
    //1
    //1
    //1
    //query.prepare("select 1 from MusicInfo where musicId=?");
    //当select 1...查询到结果后，我们需要知道是否存在
    //select exists(子查询)：子查询中如果有记录，select exists返回true
    //                      如果子查询中没有满足条件的记录，select exists返回false
    query.prepare("select exists(select 1 from MusicInfo where musicId=?)");
    query.addBindValue(musicId);//设置参数
    //执行此sql语句
    if(query.exec()==false)
    {
        qDebug()<<"查询失败:"<<query.lastError().text();
        return;
    }
    //先检测一下下一行是否有数据
    if(query.next()==true)
    {
        //拿到结果
        bool isExists=query.value(0).toBool();
        //判断music对象是否存在
        if(isExists==true)
        {
            //musicId的歌曲已经存在
            //2、如果查询此Music对象存在，此时，只需要将isLike和isHistory属性进行更新
            query.prepare("update MusicInfo set isLike=?,isHistory=? where musicId=?");
            //如果isLike是true就写1 是false就写0
            query.addBindValue(isLike?1:0);
            query.addBindValue(isHistory?1:0);
            query.addBindValue(musicId);
            //执行sql语句
            if(query.exec()==false)
            {
                //执行失败
                qDebug()<<"更新失败 "<<query.lastError().text();
            }
            qDebug()<<"更新music信息:"<<musicName<<" "<<musicId;
        }
        else
        {
            //3、如果查询此Music对象不存在，直接将music对象的属性信息插入到数据库中即可
            query.prepare("insert into MusicInfo(musicId,musicName,musicSinger,albumName,\
                                                 musicUrl,duration,isLike,isHistory)\
                          values(?,?,?,?,?,?,?,?)");
            //设置参数
            query.addBindValue(musicId);
            query.addBindValue(musicName);
            query.addBindValue(musicSinger);
            query.addBindValue(musicAlbumn);
            query.addBindValue(musicUrl.toLocalFile());//转化为本地路径
            query.addBindValue(duration);
            query.addBindValue(isLike?1:0);
            query.addBindValue(isHistory?1:0);
            //执行sql语句
            if(query.exec()==false)
            {
                //执行sql失败
                qDebug()<<"插入失败:"<<query.lastError().text();
                return;
            }
            qDebug()<<"插入music信息:"<<musicName<<" "<<musicId;
        }
    }
}
//解析元数据-根据QUrl来进行获取该音乐的信息
void Music::parseMediaMetaMusic()
{
    //1、创建媒体播放对象
    QMediaPlayer player;
    //2、设置媒体源，依靠setMedia方法解析元数据
    player.setMedia(musicUrl);
    //3、因为setMedia不会等待音乐的加载就立马返回
    /* 因此在通过mediaMeta方法获取到元数据时，需要保证媒体已经添加完毕
     * 可以通过isMetaDataAvailable检测数据是否有效
     * 如果该方法返回true，说明加载完成，可以获取各种音乐数据了
     */
    while(player.isMetaDataAvailable()==false)
    {
        QCoreApplication::processEvents();//为false就一直循环，直到为true
    }
    //此时音乐信息已经加载完毕了，可以获取有效的元数据了
    //为了保险起见，可以再检测一次
    if(player.isMetaDataAvailable()==true)
    {
        //获取音乐名称
        musicName=player.metaData("Title").toString();
        //获取音乐作者
        musicSinger=player.metaData("Author").toString();
        //获取音乐专辑
        musicAlbumn=player.metaData("AlbumTitle").toString();
        //获取音乐时长
        duration=player.metaData("Duration").toLongLong();

        //对音乐名称、音乐作者、音乐专辑信息为空时的特殊处理
        //获取文件名
        QString fileName=musicUrl.fileName();
        //找文件名中'-'的位置
        int index=fileName.indexOf('-');
        //对与musicName为""时的处理
        if(musicName.isEmpty()==true)
        {
            //检测是否从文件名中找到了'-'字符的下标
            if(index!=-1)
            {
                //"2002年的第一场雪 - 刀郎.mp3"-文件名类似这种情况
                //截取从0到index下标的子串，就是音乐名称 trimmed方法：去除前后的空格
                musicName=fileName.mid(0,index).trimmed();
            }
            else
            {
                //"2002年的第一场雪.mp3"-文件名类似这种情况
                //截取从0位置到'.'字符下标的子串，就是音乐名称
                //获取'.'位置的下标
                int pos=fileName.indexOf('.');
                musicName=fileName.mid(0,pos).trimmed();
            }
        }
        //音乐作者为空时
        if(musicSinger.isEmpty()==true)
        {
            //检测是否从文件名中找到了'-'字符的下标
            if(index!=-1)
            {
                //"2002年的第一场雪 - 刀郎.mp3"-文件名类似这种情况
                //截取从'-'字符后面开始，到'.'字符之前的子串即可
                musicSinger=fileName.mid(index+1,fileName.indexOf('.')-index-1).trimmed();
            }
            else
            {
                //"2002年的第一场雪.mp3"-文件名类似这种情况
                //如果没有音乐作者，就将名称改为未知即可
                musicSinger="未知歌手";
            }
        }
        //专辑名称为空
        if(musicAlbumn.isEmpty()==true)
        {
            musicAlbumn="未知专辑";
        }

        qDebug()<<fileName<<":"<<musicName<<":"<<musicSinger<<":"<<musicAlbumn<<":"<<duration;

    }

}
